package com.atguigu.spzx.user.service.Impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.atguigu.spyx.model.common.ResultCodeEnum;
import com.atguigu.spyx.model.common.com.atguigu.spyx.model.entity.h5.UserInfo;
import com.atguigu.spyx.model.dto.h5.UserRegistDto;
import com.atguigu.spyx.model.exception.SpzxException;
import com.atguigu.spzx.user.mapper.UserInfoMapper;
import com.atguigu.spzx.user.service.UserInfoService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import util.RegexValidateUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author LT
 * @create 2023-11-19-22:39
 */
@Service
public class UserInfoServiceImpl implements UserInfoService {

        @Resource
        UserInfoMapper userInfoMapper;
        @Resource
        StringRedisTemplate stringRedisTemplate;
        @Resource
        RedisTemplate redisTemplate;
        @Override
        public void register(UserRegistDto userRegistDto) {
            String username = userRegistDto.getUsername();
            String password = userRegistDto.getPassword();
            String nickName = userRegistDto.getNickName();
            String code = userRegistDto.getCode();
            //参数非空校验
            if(StringUtils.isEmpty(username)||
                    StringUtils.isEmpty(password)||
                    StringUtils.isEmpty(nickName)||
                    StringUtils.isEmpty(code)
            ){
                throw new SpzxException(ResultCodeEnum.ERROR , null);
            }
            //手机号格式校验
            if(!RegexValidateUtils.checkCellphone(username)){
                throw new SpzxException(ResultCodeEnum.MOBILE_ERROR , null);
            }
            //校验验证码：
            String codeKey = "user:sms:code:"+username;
            String cacheCode = stringRedisTemplate.opsForValue().get(codeKey);
            if(!StringUtils.equals(code , cacheCode)){
                //注册验证码校验失败抛出异常
                throw new SpzxException(ResultCodeEnum.LOGIN_CODE_ERROR , null);
            }
            // 验证码校验成功：清除验证码缓存   防止注册表单重复提交
            stringRedisTemplate.delete(codeKey);

            //保存数据到数据库
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername(username);
        /*
            1、修改user_info表添加salt字段： 盐 混淆密码的额外的字符串
                alter table user_info add column salt char(6) ;
            2、修改userInfo类添加salt属性
            3、注册时 生成盐，然后对密码+盐进行加密
            4、以后登录时 先查询盐 然后和登录密码一起加密 比较
         */
            String salt = RandomUtil.randomString(6);
            userInfo.setSalt(salt);
            //先对注册密码加密 然后和盐组合后再加密
            String saltpwd = DigestUtils.md5DigestAsHex(password.getBytes())+salt;
            String encodePwd = DigestUtils.md5DigestAsHex(saltpwd.getBytes());
            userInfo.setPassword(encodePwd);
            userInfo.setNickName(nickName);
            userInfo.setAvatar("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
            userInfo.setPhone(username);
            userInfo.setStatus(1);
            userInfoMapper.save(userInfo);
        }

    @Override
    public String login(UserInfo userInfo) {
        String username = userInfo.getUsername();
        String password = userInfo.getPassword();
        if (StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
            throw new SpzxException(ResultCodeEnum.ERROR , null);
        }
        UserInfo userInfo2 = userInfoMapper.findByUsername(username);
        if (userInfo2==null){
            throw new SpzxException(ResultCodeEnum.LOGIN_ERROR , null);
        }
        String dbPassword = userInfo2.getPassword();
        String saltpwd = DigestUtils.md5DigestAsHex(password.getBytes())+userInfo2.getSalt();
        String encodePwd = DigestUtils.md5DigestAsHex(saltpwd.getBytes());
//        System.out.println(userInfo2.getSalt());
//        System.out.println(dbPassword);
//        System.out.println(encodePwd);
        if (!encodePwd.equals(dbPassword)){
            throw new SpzxException(ResultCodeEnum.LOGIN_EXPIRE_ERROR , null);
        }
        String token = IdUtil.getSnowflake(1,1).nextIdStr();
        userInfo.setPassword(null);
        redisTemplate.opsForValue().set("user:login:"+token,userInfo2,7, TimeUnit.DAYS);
        return token;
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete("user:login:"+token);
    }
}
